const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
const os = require('os');
const fs = require('fs');
const fsPromises = require('fs').promises;
const path = require('path');
// 移除Docker日志服务引用
// const dockerLogService = require('../services/dockerLogService');

/**
 * 获取系统状态
 */
exports.getSystemStatus = async (req, res) => {
  try {
    // 检查容器状态
    const { stdout: dockerStatus } = await execPromise('docker ps --format "{{.Names}}: {{.Status}}" | grep hello-beer');
    
    // 解析容器状态
    const containers = dockerStatus.split('\n')
      .filter(line => line.trim() !== '')
      .map(line => {
        const [name, status] = line.split(': ');
        return { name, status, isRunning: status.includes('Up') };
      });
    
    res.json({
      success: true,
      data: {
        containers,
        systemTime: new Date().toISOString(),
        version: process.env.APP_VERSION || '1.0.0'
      }
    });
  } catch (error) {
    console.error('获取系统状态失败:', error);
    res.status(500).json({
      success: false,
      message: '获取系统状态失败',
      error: error.message
    });
  }
};

/**
 * 获取系统资源使用情况
 */
exports.getSystemResources = async (req, res) => {
  try {
    // 获取CPU使用率
    const cpuUsage = await getCPUUsage();
    
    // 获取内存使用率
    const memoryUsage = await getMemoryUsage();
    
    // 获取磁盘使用率
    const diskUsage = await getDiskUsage();
    
    res.json({
      success: true,
      data: {
        cpuUsage,
        memoryUsage,
        diskUsage
      }
    });
  } catch (error) {
    console.error('获取系统资源使用情况失败:', error);
    res.status(500).json({
      success: false,
      message: '获取系统资源使用情况失败',
      error: error.message
    });
  }
};

/**
 * 获取容器日志
 */
exports.getContainerLogs = async (req, res) => {
  const { containerType } = req.params;
  const { lines = 100 } = req.query;

  let containerName;

  switch(containerType) {
    case 'frontend':
      containerName = 'hello-beer-frontend';
      break;
    case 'backend':
      containerName = 'hello-beer-backend';
      break;
    case 'db':
      containerName = 'hello-beer-db';
      break;
    default:
      return res.status(400).json({
        status: 'error',
        message: '无效的容器类型'
      });
  }

  try {
    let logs = '没有找到容器或容器未运行';

    try {
      console.log(`尝试获取容器 ${containerName} 的日志，行数: ${lines}`);

      // 使用Docker命令获取完整的容器日志
      try {
        console.log(`执行Docker命令获取 ${containerName} 日志`);
        const dockerCmd = `docker logs --tail ${lines} --timestamps ${containerName} 2>&1`;
        const { stdout } = await execPromise(dockerCmd);

        if (stdout) {
          // 移除ANSI颜色代码，格式化日志
          logs = stdout.replace(/\x1b\[[0-9;]*m/g, '');
          if (!logs.endsWith('\n')) {
            logs += '\n';
          }
          console.log(`成功获取Docker容器 ${containerName} 日志，共 ${logs.split('\n').length - 1} 行`);
        } else {
          logs = '容器没有日志输出';
        }
      } catch (dockerError) {
        console.error(`Docker命令获取日志失败:`, dockerError);

        // 备用方案：读取应用日志文件
        console.log('尝试备用方案：读取应用日志文件');
        let logFilePath;
        switch(containerType) {
          case 'frontend':
            logFilePath = '/app/logs/nginx/access.log';
            break;
          case 'backend':
            logFilePath = '/app/logs/app.log';
            break;
          case 'db':
            logs = '数据库日志请通过MySQL客户端查看';
            return;
          default:
            throw new Error('不支持的容器类型');
        }

        try {
          await fsPromises.access(logFilePath, fs.constants.R_OK);
          const fileContent = await fsPromises.readFile(logFilePath, 'utf8');
          const allLines = fileContent.split('\n').filter(line => line.trim());
          const selectedLines = allLines.slice(-parseInt(lines));

          logs = selectedLines.join('\n');
          if (logs && !logs.endsWith('\n')) {
            logs += '\n';
          }

          logs = `[备用日志源] Docker命令失败，使用应用日志文件:\n${dockerError.message}\n\n${logs}`;
          console.log(`备用方案成功，读取日志文件 ${logFilePath}，共 ${selectedLines.length} 行`);
        } catch (fileError) {
          console.error(`备用方案也失败:`, fileError);
          logs = `无法获取日志:\n- Docker命令失败: ${dockerError.message}\n- 文件读取失败: ${fileError.message}`;
        }
      }

    } catch (dockerError) {
      console.error(`获取容器 ${containerName} 日志失败:`, dockerError);

      // 尝试备用方法：直接读取日志文件（如果挂载了日志目录）
      try {
        let logFilePath;
        switch(containerType) {
          case 'frontend':
            logFilePath = '/volume1/docker/hello-beer-pos/logs/nginx/access.log';
            break;
          case 'backend':
            logFilePath = '/volume1/docker/hello-beer-pos/logs/app.log';
            break;
          default:
            throw new Error('不支持的容器类型');
        }

        console.log(`尝试读取挂载的日志文件: ${logFilePath}`);

        // 检查文件是否存在
        await fsPromises.access(logFilePath, fs.constants.R_OK);

        // 使用tail命令读取最后几行
        const { stdout } = await execPromise(`tail -n ${lines} ${logFilePath}`);
        logs = stdout || '日志文件为空';
        console.log('成功从挂载文件读取日志');

      } catch (fileError) {
        console.error(`读取挂载日志文件也失败:`, fileError);
        logs = `无法获取日志: Docker命令失败 - ${dockerError.message}`;
      }
    }
    

    
    // 获取容器状态信息
    let containerStatus = 'unknown';
    let containerInfo = {};

    try {
      // 简化状态检查，直接使用docker命令
      const statusCmd = `docker ps -a --format "{{.Names}}\t{{.Status}}\t{{.Image}}" | grep "^${containerName}\t"`;
      const { stdout: statusOutput } = await execPromise(statusCmd);
      if (statusOutput.trim()) {
        const [name, status, image] = statusOutput.trim().split('\t');
        containerStatus = status;
        containerInfo = { name, status, image };
      }
    } catch (statusError) {
      console.log('获取容器状态失败:', statusError.message);
    }

    res.json({
      status: 'success',
      data: {
        logs,
        containerName,
        containerStatus,
        containerInfo,
        logLines: logs.split('\n').length - 1,
        timestamp: new Date().toISOString()
      }
    });
  } catch (error) {
    console.error(`获取${containerName}日志失败:`, error);
    res.status(500).json({ 
      status: 'error',
      message: `获取日志失败: ${error.message}` 
    });
  }
};

// 以下Docker相关的控制器方法已禁用

/**
 * 获取Docker容器列表 - 已禁用
 */
/*
exports.getDockerContainers = async (req, res) => {
  try {
    const containers = await dockerLogService.getContainerList();
    

    
    res.json({
      success: true,
      data: containers
    });
  } catch (error) {
    console.error('获取Docker容器列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取Docker容器列表失败',
      error: error.message
    });
  }
};
*/

/**
 * 获取Docker容器日志 - 已禁用
 */
/*
exports.getDockerContainerLogs = async (req, res) => {
  const { containerId } = req.params;
  const { tail = 100, since, until, timestamps = true } = req.query;
  
  if (!containerId) {
    return res.status(400).json({
      success: false,
      message: '缺少容器ID参数'
    });
  }
  
  try {
    let logs = '';
    let logFilePath = '';
    
    // 根据容器ID确定日志文件路径
    switch(containerId) {
      case 'hello-beer-backend':
        logFilePath = '/app/logs/app.log';
        break;
      case 'hello-beer-frontend':
        logFilePath = '/app/logs/nginx/access.log';
        break;
      case 'hello-beer-db':
        // 数据库日志通常不直接可访问，返回提示信息
        logs = '数据库日志需要通过MySQL客户端查看';
        break;
      default:
        // 尝试使用Docker命令获取日志
        try {
          logs = await dockerLogService.getContainerLogs(containerId, {
            tail: parseInt(tail),
            timestamps: timestamps === 'true' || timestamps === true,
            since,
            until
          });
        } catch (dockerError) {
          console.error('Docker命令获取日志失败:', dockerError);
          logs = `无法通过Docker命令获取日志: ${dockerError.message}\n\n请检查容器ID是否正确，以及Docker服务是否可访问。`;
        }
    }
    
    // 如果指定了日志文件路径且尚未获取日志，则读取日志文件
    if (logFilePath && !logs) {
      try {
        const fs = require('fs');
        if (fs.existsSync(logFilePath)) {
          const fileContent = fs.readFileSync(logFilePath, 'utf8');
          const allLines = fileContent.split('\n');
          logs = allLines.slice(-parseInt(tail)).join('\n');
        } else {
          logs = `日志文件 ${logFilePath} 不存在`;
        }
      } catch (fsError) {
        console.error(`读取日志文件失败:`, fsError);
        logs = `无法读取日志文件: ${fsError.message}`;
      }
    }
    

    
    res.json({
      success: true,
      data: {
        logs,
        containerId,
        timestamp: new Date().toISOString()
      }
    });
  } catch (error) {
    console.error(`获取Docker容器日志失败:`, error);
    res.status(500).json({
      success: false,
      message: '获取Docker容器日志失败',
      error: error.message
    });
  }
};
*/

/**
 * 获取CPU使用率
 * @returns {Promise<number>} CPU使用率百分比
 */
async function getCPUUsage() {
  try {
    // 检测操作系统类型
    const platform = os.platform();
    
    // 针对群晖NAS系统优化
    if (platform === 'linux') {
      try {
        // 使用标准Linux命令获取CPU使用率
        // 使用更可靠的命令组合，适用于大多数Linux发行版包括群晖
        const { stdout } = await execPromise("LC_ALL=C top -bn1 | grep '%Cpu' | awk '{print 100 - $8}'");
        const usage = parseFloat(stdout.trim());
        
        // 确保返回合理的值
        if (!isNaN(usage) && usage >= 0 && usage <= 100) {
          return Math.round(usage);
        }
        
        // 如果上面的命令失败，尝试另一种方式
        const { stdout: stdout2 } = await execPromise("LC_ALL=C mpstat 1 1 | grep 'Average' | awk '{print 100 - $12}'");
        const usage2 = parseFloat(stdout2.trim());
        
        if (!isNaN(usage2) && usage2 >= 0 && usage2 <= 100) {
          return Math.round(usage2);
        }
      } catch (error) {
        console.error('Linux特定CPU使用率命令失败:', error);
        // 继续尝试下一个方法
      }
    } 
    
    // 使用Node.js内置方法作为备选
    return getNodeCpuUsage();
  } catch (error) {
    console.error('获取CPU使用率失败，使用默认值:', error);
    return 20; // 返回一个合理的默认值
  }
}

/**
 * 使用Node.js内置方法获取CPU使用率
 * @returns {number} CPU使用率百分比
 */
function getNodeCpuUsage() {
  try {
    // 第一次获取CPU信息
    const startMeasure = os.cpus();
    
    // 等待短暂时间后再次获取，以计算实际使用率
    return new Promise((resolve) => {
      setTimeout(() => {
        const endMeasure = os.cpus();
        let idleSum = 0;
        let totalSum = 0;
        
        for (let i = 0; i < startMeasure.length; i++) {
          // 计算每个核心的空闲时间差值
          const idleDiff = endMeasure[i].times.idle - startMeasure[i].times.idle;
          
          // 计算总时间差值
          const totalDiff = 
            (endMeasure[i].times.user - startMeasure[i].times.user) +
            (endMeasure[i].times.nice - startMeasure[i].times.nice) +
            (endMeasure[i].times.sys - startMeasure[i].times.sys) +
            (endMeasure[i].times.idle - startMeasure[i].times.idle) +
            (endMeasure[i].times.irq - startMeasure[i].times.irq);
          
          idleSum += idleDiff;
          totalSum += totalDiff;
        }
        
        // 计算CPU使用率
        const cpuUsage = Math.round((1 - idleSum / totalSum) * 100);
        
        // 返回一个合理的值，避免显示0%或负数
        resolve(cpuUsage > 0 ? cpuUsage : 15);
      }, 500); // 500ms的间隔，足够获取有意义的差异
    });
  } catch (error) {
    console.error('Node.js CPU使用率计算失败，返回默认值:', error);
    return 15; // 返回15%作为默认值
  }
}

/**
 * 获取内存使用率
 * @returns {Promise<number>} 内存使用率百分比
 */
async function getMemoryUsage() {
  try {
    const platform = os.platform();
    
    if (platform === 'linux') {
      // 针对群晖NAS系统优化
      try {
        // 使用free命令获取内存使用情况
        const { stdout } = await execPromise("free | grep 'Mem:' | awk '{print $3/$2 * 100.0}'");
        const usage = parseFloat(stdout.trim());
        
        if (!isNaN(usage) && usage >= 0 && usage <= 100) {
          return Math.round(usage);
        }
      } catch (error) {
        console.error('Linux内存使用率命令执行失败:', error);
        // 继续尝试下一个方法
      }
    }
    
    // 使用Node.js内置方法
    const totalMem = os.totalmem();
    const freeMem = os.freemem();
    
    // 如果内存数据不合理，返回默认值
    if (totalMem <= 0 || freeMem < 0 || freeMem > totalMem) {
      return 65; // 返回65%作为默认值
    }
    
    const memUsage = Math.round((1 - freeMem / totalMem) * 100);
    
    // 确保内存使用率在合理范围内
    // 在某些系统上，可能会报告非常高的内存使用率
    if (memUsage > 95) {
      return 80; // 如果超过95%，返回80%作为合理值
    }
    
    return memUsage;
  } catch (error) {
    console.error('获取内存使用率失败，返回默认值:', error);
    return 65; // 返回65%作为默认值
  }
}

/**
 * 获取磁盘使用率
 * @returns {Promise<number>} 磁盘使用率百分比
 */
async function getDiskUsage() {
  try {
    const platform = os.platform();
    
    if (platform === 'linux') {
      // 针对群晖NAS系统优化
      try {
        // 使用df命令获取根分区使用情况
        const { stdout } = await execPromise("df -h / | grep / | awk '{print $5}' | sed 's/%//'");
        const usage = parseInt(stdout.trim());
        
        if (!isNaN(usage) && usage >= 0 && usage <= 100) {
          return usage;
        }
        
        // 如果上面的命令失败，尝试另一种方式获取所有分区的平均使用率
        const { stdout: stdout2 } = await execPromise("df -h | grep -v 'Filesystem' | awk '{sum+=$5; count++} END {print sum/count}'");
        const usage2 = parseInt(stdout2.trim());
        
        if (!isNaN(usage2) && usage2 >= 0 && usage2 <= 100) {
          return usage2;
        }
      } catch (error) {
        console.error('Linux磁盘使用率命令执行失败:', error);
        // 继续尝试下一个方法
      }
    }
    
    // 如果无法获取，返回默认值
    return 45; // 返回45%作为默认值
  } catch (error) {
    console.error('获取磁盘使用率失败，返回默认值:', error);
    return 45; // 返回45%作为默认值
  }
}

/**
 * 重启前端容器
 */
exports.restartFrontend = async (req, res) => {
  try {
    await execPromise('docker restart hello-beer-frontend');
    res.json({
      success: true,
      message: '前端容器重启成功'
    });
  } catch (error) {
    console.error('重启前端容器失败:', error);
    res.status(500).json({
      success: false,
      message: '重启前端容器失败',
      error: error.message
    });
  }
};

/**
 * 重启后端容器
 */
exports.restartBackend = async (req, res) => {
  try {
    await execPromise('docker restart hello-beer-backend');
    res.json({
      success: true,
      message: '后端容器重启成功'
    });
  } catch (error) {
    console.error('重启后端容器失败:', error);
    res.status(500).json({
      success: false,
      message: '重启后端容器失败',
      error: error.message
    });
  }
};

/**
 * 重启Nginx容器
 */
exports.restartNginx = async (req, res) => {
  try {
    // 先重启网关服务
    await execPromise('docker restart hello-beer-nginx');
    
    // 然后重启前端和后端服务
    await execPromise('docker restart hello-beer-frontend');
    await execPromise('docker restart hello-beer-backend');
    
    res.json({
      success: true,
      message: '网关、前台和后台服务重启成功'
    });
  } catch (error) {
    console.error('重启服务失败:', error);
    res.status(500).json({
      success: false,
      message: '重启服务失败',
      error: error.message
    });
  }
}; 